package com.gxa.weixing.core.util;

import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.regex.Pattern;

/**
 * 校验字符串的工具类
 *
 * @author YXQ
 * @date 2021/10/26 22:44
 */
public class StringUtil {
    /**
     * 判断字符串是否为空
     *
     * @param str 待判断的字符串
     * @return 空返回true
     */
    public static boolean isEmpty(String str) {
        // 通过str.trim去掉字符串多余的空格
        return str == null || "".equals(str.trim());
    }

    /**
     * 判断是否是合法手机号
     *
     * @param phone 被校验的手机号
     * @return 合法true
     */
    public static boolean isPhoneNumber(String phone) {
        return phone.matches("^1(3\\d|4[5-9]|5[0-35-9]|6[567]|7[0-8]|8\\d|9[0-35-9])\\d{8}$");
    }

    /**
     * 判断查询的条件是否为空
     *
     * @param s 字符串
     * @return 合法true
     */
    public static boolean isBlankOrNull(String s) {
        return StringUtils.isBlank(s) && StringUtils.isEmpty(s);
    }

    /**
     * 1.“@”的左边限制：
     * 由a～z的英文字母（不区分大小写）开头
     * 可由英文字母、0～9的数字、点、减号或下划线组成
     * 长度为3～18个字符
     * 不能以点、减号结尾
     * 2.“@”的右边限制：
     * 只能有一个点，点和"@"之间不能为空
     * 可由英文字母、0～9的数字、点、减号或下划线组成
     * 不能以点、减号或下划线结尾
     *
     * @param email 被校验的手邮箱
     * @return 合法true
     */
    public static boolean isEmail(String email) {
        return Pattern.matches("^(\\w+([-.][A-Za-z0-9]+)*){3,18}@\\w+([-.][A-Za-z0-9]+)*\\.\\w+([-.][A-Za-z0-9]+)*$", email);
    }

    public static boolean isIDNumber(String IDNumber) {
        if (IDNumber == null || "".equals(IDNumber)) {
            return false;
        }
        // 定义判别用户身份证号的正则表达式（15位或者18位，最后一位可以为字母）
        String regularExpression = "(^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|" +
                "(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}$)";
        //假设18位身份证号码:41000119910101123X  410001 19910101 123X
        //^开头
        //[1-9] 第一位1-9中的一个      4
        //\\d{5} 五位数字           10001（前六位省市县地区）
        //(18|19|20)                19（现阶段可能取值范围18xx-20xx年）
        //\\d{2}                    91（年份）
        //((0[1-9])|(10|11|12))     01（月份）
        //(([0-2][1-9])|10|20|30|31)01（日期）
        //\\d{3} 三位数字            123（第十七位奇数代表男，偶数代表女）
        //[0-9Xx] 0123456789Xx其中的一个 X（第十八位为校验值）
        //$结尾

        //假设15位身份证号码:410001910101123  410001 910101 123
        //^开头
        //[1-9] 第一位1-9中的一个      4
        //\\d{5} 五位数字           10001（前六位省市县地区）
        //\\d{2}                    91（年份）
        //((0[1-9])|(10|11|12))     01（月份）
        //(([0-2][1-9])|10|20|30|31)01（日期）
        //\\d{3} 三位数字            123（第十五位奇数代表男，偶数代表女），15位身份证不含X
        //$结尾
        boolean matches = IDNumber.matches(regularExpression);
        //判断第18位校验值
        int num = 18;
        if (matches) {

            if (IDNumber.length() == num) {
                try {
                    char[] charArray = IDNumber.toCharArray();
                    //前十七位加权因子
                    int[] idCardWi = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
                    //这是除以11后，可能产生的11位余数对应的验证码
                    String[] idCardY = {"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"};
                    int sum = 0;
                    for (int i = 0; i < idCardWi.length; i++) {
                        int current = Integer.parseInt(String.valueOf(charArray[i]));
                        int count = current * idCardWi[i];
                        sum += count;
                    }
                    char idCardLast = charArray[17];
                    int idCardMod = sum % 11;
                    if (idCardY[idCardMod].toUpperCase().equals(String.valueOf(idCardLast).toUpperCase())) {
                        return true;
                    } else {
                        return false;
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }

        }
        return matches;
    }


    /**
     * 把 Thu Dec 14 00:00:00 CST 2017 转换成自己想要的格式
     *
     * @param date
     * @param pattern 为自己定义的类型如“yyyy-MM-dd”
     * @return
     */
    public static String dateStringFormat(String date, String pattern) {
        if (date == null || pattern == null) {
            return null;
        }
        try {
            Date formDate = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", Locale.US).parse(date);
            return new SimpleDateFormat(pattern, Locale.CHINA).format(formDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 把 yyyy-MM-dd HH:mm:ss的字符串时间 转换成 date类型
     *
     * @param date 时间字符串
     * @return 返回Date类型的时间
     */
    public static Date StringFormatDate(String date) throws ParseException {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return simpleDateFormat.parse(date);
    }


    /**
     * 将一个字符串转化为输入流
     *
     * @param sInputString 待转化的字符串
     * @return 二进制的流
     */
    public static InputStream getStringStream(String sInputString) {
        if (sInputString != null && !"".equals(sInputString.trim())) {
            try {
                ByteArrayInputStream tInputStringStream = new ByteArrayInputStream(sInputString.getBytes());
                return tInputStringStream;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 将输入流转换成字符串
     *
     * @param inputStream 输入流
     * @return 字符串
     */
    public static String inputStreamToString(InputStream inputStream) {
        StringBuffer buffer = new StringBuffer();
        InputStreamReader inputStreamReader;
        try {
            inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            // 释放资源
            bufferedReader.close();
            inputStreamReader.close();
            inputStream.close();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer.toString();
    }

    public static Boolean isNum(String s) {
        return Pattern.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$", s);
    }
}
